home *** CD-ROM | disk | FTP | other *** search
- #include "stdafx.h"
-
- #include "MstructDlg.h"
- #include "TurretDlg.h"
-
- cEditable *editables = 0;
- int selectionbox_active = FALSE, snap_to_grid = FALSE;
-
- static cBox back_selection, game_selection;
- static int tmp_x, tmp_y, tmp_x2, tmp_y2, dist;
- static cEditable *found;
-
- cEditable::cEditable(cEditable **list, cGameObject *_obj, int select)
- {
- ASSERT(_obj != 0);
-
- obj = _obj;
- sub_editables = 0;
- selected = select;
-
- // Add to list
-
- add((cList **)list);
-
- // Set surface
-
- set_surface(obj->surface);
-
- // Create pointer to this in original object
-
- if (obj->editable == 0)
- obj->editable = this;
- }
-
- cEditable::~cEditable()
- {
- // Make sure no pointer remains to this object
-
- if (left_editable == this)
- left_editable = 0;
-
- // Delete sub editables
-
- sub_editables->delete_list();
-
- // Remove binding with original object
-
- if (obj->editable == this)
- obj->editable = 0;
- }
-
- static int find_editable(cEditable *e)
- {
- int d = d_square(e->x - tmp_x, e->y - (tmp_y - game_surface->start + e->obj->surface->start));
-
- if (d < dist)
- dist = d, found = e;
-
- return TRUE;
- }
-
- cEditable *cEditable::find(int x, int y)
- {
- found = 0, dist = 25, tmp_x = x, tmp_y = y;
-
- walk_editables(find_editable);
-
- return found;
- }
-
- static int check_remove_editable(cEditable *e)
- {
- return !e->selected && !e->on_screen();
- }
-
- void cEditable::make_editables()
- {
- cEditable *e, *n;
-
- // If selection box is not active then delete editables that go off screen
- // and that are not selected
-
- if (!selectionbox_active)
- for (e = editables; e != 0; e = n)
- {
- n = (cEditable *)e->next;
-
- if (check_remove_editable(e) && e->walk_sub_editables(check_remove_editable))
- delete e;
- }
-
- // Loop through all objects that can be edited and add the ones that are
- // not in the list yet
-
- for (int i = 0; objtypes[i].type != 0; i++)
- if (!objtypes[i].list_occured_earlier)
- for (cGameObject *g = *objtypes[i].onscreen; g != 0; g = (cGameObject *)g->next)
- if (g->editable == 0 && g->surface_visible())
- g->create_editables();
- }
-
- void cEditable::delete_editables()
- {
- editables->delete_list();
- }
-
- void cEditable::editables_layer_change()
- {
- // First delete everything that is not in a visible layer
-
- cEditable *e, *n;
-
- for (e = editables; e != 0; e = n)
- {
- n = (cEditable *)e->next;
-
- if (!e->surface_visible())
- delete e;
- }
-
- // Then call standard function to create editables
-
- cEditable::make_editables();
- }
-
- static int write_editable(cEditable *e)
- {
- e->write();
-
- return TRUE;
- }
-
- void cEditable::write_editables()
- {
- // Walk through editables and write them
-
- walk_editables(write_editable);
-
- // Write selection box
-
- if (selectionbox_active)
- {
- if (view_backgroundarea)
- rect(back_surface, back_selection.x1, back_selection.y1, back_selection.x2, back_selection.y2, blue);
-
- if (view_gamearea)
- rect(game_surface, game_selection.x1, game_selection.y1, game_selection.x2, game_selection.y2, white);
- }
- }
-
- static int check_drag_editable(cEditable *e)
- {
- if (!e->selected)
- return TRUE;
-
- if (e->surface == back_surface)
- return e->check_drag(tmp_x, tmp_y);
- else
- return e->check_drag(tmp_x2, tmp_y2);
- }
-
- static int drag_editable(cEditable *e)
- {
- if (e->selected)
- {
- if (e->surface == back_surface)
- e->drag(tmp_x, tmp_y);
- else
- e->drag(tmp_x2, tmp_y2);
- }
-
- return TRUE;
- }
-
- void cEditable::drag_editables(int dx_back, int dy_back, int dx_game, int dy_game)
- {
- // Check if there is change
-
- if (dx_back == 0 && dy_back == 0 && dx_game == 0 && dy_game == 0)
- return;
-
- // Setup variables
-
- tmp_x = dx_back, tmp_y = dy_back;
- tmp_x2 = dx_game, tmp_y2 = dy_game;
-
- // Check if drag is possible
-
- if (!walk_editables(check_drag_editable))
- return;
-
- // Drag editables
-
- walk_editables(drag_editable);
- }
-
- void cEditable::snap_editables_to_grid()
- {
- int dy = (left_editable->y - left_editable->obj->surface->start + game_surface->start) % LEVEL_VTICK;
-
- if (dy < LEVEL_VTICK / 2)
- dy = - dy;
- else
- dy = LEVEL_VTICK - dy;
-
- drag_editables(0, dy, 0, dy);
- }
-
- static int unselect_editable(cEditable *e)
- {
- e->selected = FALSE;
-
- return TRUE;
- }
-
- void cEditable::unselect_editables()
- {
- walk_editables(unselect_editable);
- }
-
- static int check_anything_selected(cEditable *e)
- {
- return !e->selected;
- }
-
- int cEditable::anything_selected()
- {
- return !walk_editables(check_anything_selected);
- }
-
- static int delete_selected_editable(cEditable *e)
- {
- if (e->selected)
- e->remove();
-
- return TRUE;
- }
-
- void cEditable::delete_selected_editables()
- {
- // Delete editables and objects
-
- walk_editables(delete_selected_editable);
-
- // Delete things that can be generated during the previous step
-
- parts->delete_list();
- effects->delete_list();
- }
-
- void cEditable::set_rectangle(int x, int y)
- {
- back_selection.x1 = x;
- back_selection.y1 = y - game_surface->start + back_surface->start;
-
- game_selection.x1 = x;
- game_selection.y1 = y;
-
- set_edge_rectangle(x, y);
-
- selectionbox_active = TRUE;
- }
-
- void cEditable::set_edge_rectangle(int x, int y)
- {
- back_selection.x2 = x;
- back_selection.y2 = y - game_surface->start + back_surface->start;
-
- game_selection.x2 = x;
- game_selection.y2 = y;
- }
-
- static int select_editable(cEditable *e)
- {
- if (e->surface == game_surface)
- {
- if (in(e->x, game_selection.x1, game_selection.x2) && in(e->y, game_selection.y1, game_selection.y2))
- e->selected = !e->selected;
- }
- else if (e->surface == back_surface)
- {
- if (in(e->x, back_selection.x1, back_selection.x2) && in(e->y, back_selection.y1, back_selection.y2))
- e->selected = !e->selected;
- }
-
- return TRUE;
- }
-
- void cEditable::rectangle_to_selection()
- {
- // Turn of selection mode
-
- selectionbox_active = FALSE;
-
- // Sort coordinates
-
- sort2(back_selection.x1, back_selection.x2);
- sort2(back_selection.y1, back_selection.y2);
-
- sort2(game_selection.x1, game_selection.x2);
- sort2(game_selection.y1, game_selection.y2);
-
- // Toggle selection in the selection box
-
- walk_editables(select_editable);
- }
-
- int cEditable::walk_editables(int (*callback)(cEditable *e))
- {
- cEditable *e, *n;
-
- for (e = editables; e != 0; e = n)
- {
- n = (cEditable *)e->next;
-
- if (!e->walk_sub_editables(callback))
- return FALSE;
-
- if (!callback(e))
- return FALSE;
- }
-
- return TRUE;
- }
-
- int cEditable::walk_sub_editables(int (*callback)(cEditable *e))
- {
- cEditable *e, *n;
-
- for (e = sub_editables; e != 0; e = n)
- {
- n = (cEditable *)e->next;
-
- if (e->sub_editables != 0 && !e->sub_editables->walk_sub_editables(callback))
- return FALSE;
-
- if (!callback(e))
- return FALSE;
- }
-
- return TRUE;
- }
-
- void cEditable::write()
- {
- if (selected)
- rectfill(surface, x - 2, y - 2, x + 2, y + 2, green);
- else
- rect(surface, x - 2, y - 2, x + 2, y + 2, green);
- }
-
- int cEditable::check_drag(int dx, int dy)
- {
- return TRUE;
- }
-
- void cEditable::drag(int dx, int dy)
- {
- }
-
- void cEditable::remove()
- {
- cGameObject *t = obj;
-
- delete this;
- delete t;
- }
-
- void cEditable::create_context_menu(CMenu *menu)
- {
- }
-
- void cEditable::execute_context_menu(int id)
- {
- }
-
- cEditableGameObject::cEditableGameObject(cGameObject *obj, int select)
- : cEditable(&editables, obj, select)
- {
- set_position(obj->x, obj->y);
- }
-
- int cEditableGameObject::check_drag(int dx, int dy)
- {
- int xe = obj->x + dx, ye = obj->y + dy;
-
- obj->set_position(xe, ye);
-
- int rv = obj->x == xe && obj->y == ye;
-
- obj->set_position(x, y);
-
- return rv;
- }
-
- void cEditableGameObject::drag(int dx, int dy)
- {
- // Move object
-
- obj->make_dirty();
- obj->set_position(obj->x + dx, obj->y + dy);
- obj->update_list();
- obj->make_dirty();
-
- // Set marker position
-
- set_position(obj->x, obj->y);
- }
-
- cEditableWaypoint::cEditableWaypoint(cGameObject *obj, cSpot *_waypoint, int select)
- : cEditable(&obj->editable->sub_editables, obj, select)
- {
- waypoint = _waypoint;
-
- set_position(waypoint->x, waypoint->y);
- }
-
- void cEditableWaypoint::write()
- {
- if (waypoint->prev == 0)
- dashedline(surface, x, y, obj->x, obj->y, gray);
- else
- dashedline(surface, x, y, ((cSpot *)waypoint->prev)->x, ((cSpot *)waypoint->prev)->y, white);
-
- cEditable::write();
- }
-
- int cEditableWaypoint::check_drag(int dx, int dy)
- {
- return x + dx >= surface->edge && x + dx < surface->w - surface->edge;
- }
-
- void cEditableWaypoint::drag(int dx, int dy)
- {
- waypoint->set_position(waypoint->x + dx, waypoint->y + dy);
-
- set_position(waypoint->x, waypoint->y);
- }
-
- void cEditableWaypoint::remove()
- {
- cSpot *t = waypoint;
-
- delete this;
- delete t;
- }
-
- void cEditableWaypoint::create_context_menu(CMenu *menu)
- {
- menu->AppendMenu(MF_ENABLED, ID_CONTEXT_0, _T("Insert Point &After"));
- menu->AppendMenu(MF_ENABLED, ID_CONTEXT_1, _T("Insert Point &Before"));
- menu->AppendMenu(MF_ENABLED, ID_CONTEXT_2, _T("&Delete"));
- }
-
- void cEditableWaypoint::execute_context_menu(int id)
- {
- cSpot *s;
-
- switch(id)
- {
- case 0:
- // Insert waypoint after this one
-
- s = new cSpot(&obj->waypoints, waypoint->next == 0? x + 10 : (((cSpot *)waypoint->next)->x + x) / 2, waypoint->next == 0? y + 10 : (((cSpot *)waypoint->next)->y + y) / 2);
- s->move_after(waypoint);
-
- // Create editable for it
-
- new cEditableMovingStructureWaypoint(obj, s, FALSE);
-
- break;
-
- case 1:
- // Insert waypoint before this one
-
- s = new cSpot(&obj->waypoints, ((waypoint->prev == 0? obj->x : ((cSpot *)waypoint->prev)->x) + x) / 2, ((waypoint->prev == 0? obj->y : ((cSpot *)waypoint->prev)->y) + y) / 2);
- s->move_before(waypoint);
-
- // Create editable for it
-
- new cEditableMovingStructureWaypoint(obj, s, FALSE);
-
- break;
-
- case 2:
- // Delete this editable
-
- remove();
-
- break;
- }
- }
-
- void cEditableMovingStructure::create_context_menu(CMenu *menu)
- {
- menu->AppendMenu(MF_ENABLED, ID_CONTEXT_0, _T("&Add Point"));
- menu->AppendMenu(MF_SEPARATOR, 0, _T(""));
- menu->AppendMenu(MF_ENABLED, ID_CONTEXT_1, _T("&Properties..."));
- }
-
- void cEditableMovingStructure::execute_context_menu(int id)
- {
- cSpot *s;
-
- switch(id)
- {
- case 0:
- // Create waypoint
-
- s = new cSpot(&obj->waypoints, obj->waypoints == 0? obj->x + 10 : (obj->waypoints->x + obj->x) / 2, obj->waypoints == 0? obj->y + 10 : (obj->waypoints->y + obj->y) / 2);
- s->move_before(obj->waypoints);
-
- // Create editable for it
-
- new cEditableMovingStructureWaypoint(obj, s, FALSE);
-
- break;
-
- case 1:
- CMstructDlg d((cMovingStructure *)obj);
- d.DoModal();
- break;
- }
- }
-
- void cEditableMovingStructureWaypoint::create_context_menu(CMenu *menu)
- {
- cEditableWaypoint::create_context_menu(menu);
-
- menu->AppendMenu(MF_SEPARATOR, 0, _T(""));
- menu->AppendMenu(MF_ENABLED, ID_CONTEXT_3, _T("&Properties..."));
- }
-
- void cEditableMovingStructureWaypoint::execute_context_menu(int id)
- {
- if (id == 3)
- {
- CMstructDlg d((cMovingStructure *)obj);
- d.DoModal();
- }
- else
- {
- cEditableWaypoint::execute_context_menu(id);
- }
- }
-
- void cEditableTurret::write()
- {
- // Write dashed lines for rotation start and end
-
- dashedline(surface, x, y, x + (int)(cos(((cTurret *)obj)->rotation_start) * TURRET_DASH_LINE), y + (int)(sin(((cTurret *)obj)->rotation_start) * TURRET_DASH_LINE), green);
- dashedline(surface, x, y, x + (int)(cos(((cTurret *)obj)->rotation_end) * TURRET_DASH_LINE), y + (int)(sin(((cTurret *)obj)->rotation_end) * TURRET_DASH_LINE), red);
-
- // Call base class
-
- cEditableGameObject::write();
- }
-
- void cEditableTurret::create_context_menu(CMenu *menu)
- {
- menu->AppendMenu(MF_ENABLED, ID_CONTEXT_0, _T("&Properties..."));
- }
-
- void cEditableTurret::execute_context_menu(int)
- {
- CTurretDlg d((cTurret *)obj);
- d.DoModal();
- }